package com.tvunetworks.center.device.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.pagehelper.PageInfo;
import com.tvunetworks.center.common.constant.LocalConstant;
import com.tvunetworks.center.common.model.ExtendExternal;
import com.tvunetworks.center.common.model.SearchDeviceParam;
import com.tvunetworks.center.common.model.UserBehavior;
import com.tvunetworks.center.common.model.UserCondition;
import com.tvunetworks.center.common.model.dto.grid.AcceptedGrid;
import com.tvunetworks.center.common.util.JsonUtil;
import com.tvunetworks.center.common.util.MyUtil;
import com.tvunetworks.center.common.util.Result;
import com.tvunetworks.center.common.util.ResultUtil;
import com.tvunetworks.center.device.constant.CommandConstant;
import com.tvunetworks.center.device.mapper.MyDeviceMapper;
import com.tvunetworks.center.device.mapper.UserConditionMapper;
import com.tvunetworks.center.device.mapper.UserDeviceMapper;
import com.tvunetworks.center.device.mapper.UserDeviceOperationMapper;
import com.tvunetworks.center.device.model.ComparatorName;
import com.tvunetworks.center.device.model.DeviceReport;
import com.tvunetworks.center.device.model.json.DeviceSearchStatus;
import com.tvunetworks.center.device.model.json.PageParam;
import com.tvunetworks.center.device.model.vo.DeviceVo;
import com.tvunetworks.center.device.service.DeviceService;
import com.tvunetworks.center.device.service.ReceiverControlService;
import com.tvunetworks.center.device.service.UserDeviceService;
import com.tvunetworks.center.device.service.feign.*;
import com.tvunetworks.center.device.util.ExcelUtil;
import com.tvunetworks.center.device.util.PageBar;
import com.tvunetworks.center.device.util.RandomUtil;
import com.tvunetworks.center.device.util.RedisUtil;
import com.tvunetworks.center.gs.model.Device;
import com.tvunetworks.center.gs.model.DeviceExtend;
import com.tvunetworks.center.gs.model.UserDeviceOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: tvucc-aggregator
 * @description: UserDeviceServiceImpl
 * @author lebronchen
 * @create: 2019-08-01 15:28
 **/
@Service
@Slf4j
public class UserDeviceServiceImpl implements UserDeviceService {

    @Value("${defaultLivePeerName}")
    private String defaultLivePeerName;

    @Autowired
    private GcsManageFeignService gcsManageFeignService;
    @Autowired
    private TpcFeignService tpcFeignService;
    @Autowired
    private UserDeviceMapper userDeviceMapper;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private UserDeviceOperationMapper userDeviceOperationMapper;
    @Autowired
    private UserConditionMapper userConditionMapper;
    @Autowired
    private UserFeignService userFeignService;
    @Value("${ext.type}")
    private String sourceType;
    @Autowired
    private DevicePairService devicePairService;
    @Autowired
    private GridFeignService gridFeignService;
    @Autowired
    private TokenFeignService tokenFeignService;
    @Autowired
    private MyDeviceMapper myDeviceMapper;
    @Autowired
    private ReceiverControlService receiverControlService;
    @Autowired
    private DeviceExtraFeign deviceExtraFeign;
    @Autowired
    private RedisUtil redisUtil;
    @Value("${allTPeerID}")
    private String allTPeerID;
    @Value("${allRPeerID}")
    private String allRPeerID;
    @Value("${rbasicInfo}")
    private String rBasicInfo;
    @Value("${tbasicInfo}")
    private String tBasicInfo;
    @Value("${gridServer.url}")
    private String gridserver;
    @Value("${tracking.selection}")
    private Integer selection;
    @Value("${tracking.delayQueryTime}")
    private Integer delayQueryTime;
    @Value("${tracking.manualIncrementTime}")
    private String manualIncrementTime;
    @Value("${tracking.incrementalRangeTime}")
    private String incrementalRangeTime;
    @Value("${tracking.mapStep}")
    private String mapStep;

    private int i = 1;

    @Override
    public List<Device> listRPSDevice(String userId, SearchDeviceParam param) {
        if (!param.isPack() && !param.isReceiver()) {
            return new ArrayList<>();
        }
        if (!param.isLiving() && !param.isOnline() && !param.isOffline()) {
            return new ArrayList<>();
        }
        String condition = param.getCondition();
        condition = MyUtil.formatCondition(condition);

        List<Device> resultList = new ArrayList<>();
        List<String> peerIds = userDeviceMapper.listRPSDevice(userId, param.isReceiver(), param.isPack(), condition);
        if (CollectionUtils.isEmpty(peerIds)) {
            return new ArrayList<>();
        }
        List<Device> devices = deviceService.listCurrentDevice(peerIds);
        if (CollectionUtils.isEmpty(devices)) {
            return new ArrayList<>();
        }
        for (Device device : devices) {
            String status = device.getStatus();
            if (StringUtils.isBlank(status)) {
                status = "0";
            }
            boolean statusExist = param.isStatusExistByR(status);
            if (!statusExist) {
                continue;
            }
            resultList.add(device);
        }
        return resultList;
    }

    @Override
    public Set<String> getDeviceIdByUser(String userId) {
        return userDeviceMapper.getDeviceIdByUser(userId);
    }

    @Override
    public PageBar<DeviceExtend> getReceiverList(PageParam pageParam) throws Exception {
        PageBar<DeviceExtend> pb = new PageBar<DeviceExtend>();
        DeviceSearchStatus searchStatus = pageParam.getDeviceSearchStatus();
        List<Device> resultList = new ArrayList<Device>();
        List<DeviceExtend> result = new ArrayList<DeviceExtend>();
        if (searchStatus.isNull()) {
            //live,online,offline一个都没选
            return pb;
        }
//        logger.error("====getReceiverList ====1");
        //如果用户有cloudRlive功能，那么查询就要少查一条数据
/*		if(chckeUserCloudRLiveFeature(userId)){
			if(pageParam.getPageSize() > 0){
				pageParam.setPageSize(pageParam.getPageSize()-1);
			}
		}*/
        //获取用户下所有所有符合条件的peerId(这里没筛选状态，因为DB中状态不准确)
        List<String> peerIdList = this.listPeerIdsByUserId(pageParam);
        if (peerIdList == null || peerIdList.size() == 0) {
            return pb;
        }
        //从memcached中获取设备信息
        List<Device> allList = deviceService.listCurrentDevice(peerIdList);
        String userId = pageParam.getUserId();
        String parentId = userDeviceMapper.selectParentId(userId);
        if (allList != null && allList.size() > 0) {
            // filter by status
            String status = searchStatus.getStatus();
            if (StringUtils.isEmpty(parentId)) {
                for (Device device : allList) {
                    //添加bookmark device 信息
                    //userDeviceBookmark信息
                    Result<Object> bookmarkDeviceList = userFeignService.listUserDeviceBookmarksByPeerId(pageParam.getUserId(), device.getPeerId());
                    if (bookmarkDeviceList != null) {
                        List<Map> objectList = (List<Map>) bookmarkDeviceList.getResult();
                        if ( objectList.size() > 0) {
                            Map userBookrmarkMap = new HashMap();
                            for (Map bookmarkDevice : objectList) {

                                String bookmarkId = bookmarkDevice.get("bookmarkId").toString();
                                Result<Object> userBookmarkVoList = userFeignService.getAllParentBookmarkTree(pageParam.getUserId(), bookmarkId);
                                if (userBookmarkVoList == null) {
                                    continue;
                                }
                                userBookrmarkMap.put(bookmarkId, userBookmarkVoList.getResult());
                            }
                            if (userBookrmarkMap.size() > 0) {
                                device.setUserBookmarkDevice(userBookrmarkMap);
                            }
                        }
                        String stat = "0";
                        if (StringUtils.isNotEmpty(device.getStatus())) {
                            stat = device.getStatus();
                        }
                        if (status.indexOf(stat) > -1) {
                            resultList.add(device);
                        }
                    }
                }
            } else {
                for (Device device : allList) {
                    //添加bookmark device 信息
                    //userDeviceBookmark信息
                    Result<Object> bookmarkDeviceList = userFeignService.listUserDeviceBookmarksByPeerId(pageParam.getUserId(), device.getPeerId());
                    Result<Object> parentBookmarkDeviceList = userFeignService.listUserDeviceBookmarksByPeerId(parentId, device.getPeerId());
                    if (parentBookmarkDeviceList != null) {
                        List<Map> parentDeviceList = (List<Map>) parentBookmarkDeviceList.getResult();
                        List<Map> ownDeviceList = (List<Map>) bookmarkDeviceList.getResult();
                        if ( parentDeviceList.size() > 0) {
                            Map parentBookrmarkMap = new HashMap();
                            for (Map bookmarkDevice : parentDeviceList) {

                                String bookmarkId = bookmarkDevice.get("bookmarkId").toString();
                                Result<Object> parentBookmarkVoList = userFeignService.getAllParentBookmarkTree(parentId, bookmarkId);
                                if (parentBookmarkVoList == null) {
                                    continue;
                                }
                                parentBookrmarkMap.put(bookmarkId, parentBookmarkVoList.getResult());
                            }
                            if (parentBookrmarkMap.size() > 0) {
                                device.setParentBookmarkDevice(parentBookrmarkMap);
                            }
                        }

                        if (ownDeviceList != null && ownDeviceList.size() > 0) {
                            Map ownBookrmarkMap = new HashMap();
                            for (Map bookmarkDevice : ownDeviceList) {

                                String bookmarkId = bookmarkDevice.get("bookmarkId").toString();
                                Result<Object> ownBookmarkVoList = userFeignService.getAllParentBookmarkTree(pageParam.getUserId(), bookmarkId);
                                if (ownBookmarkVoList == null) {
                                    continue;
                                }
                                ownBookrmarkMap.put(bookmarkId, ownBookmarkVoList.getResult());
                            }
                            if (ownBookrmarkMap.size() > 0) {
                                device.setUserBookmarkDevice(ownBookrmarkMap);
                            }
                        }
                        String stat = "0";
                        if (StringUtils.isNotEmpty(device.getStatus())) {
                            stat = device.getStatus();
                        }
                        if (status.indexOf(stat) > -1) {
                            resultList.add(device);
                        }
                    }
                }
            }
        }
        //addCloudDeviceToList(userId, resultList);
        List<Device> resultListsort = new ArrayList<Device>();
        if (resultList != null && resultList.size() > 0) {
//            logger.error("====getReceiverList ====2"+JSONObject.toJSONString(resultList));
            if (searchStatus.getSort()) {
                resultListsort = listSort(resultList);
            } else {
                resultListsort = listDynamicSort(resultList);
            }
            for (Device device : resultListsort) {
                if (StringUtils.isBlank(device.getLivePeerId())) {
                    device.setLivePeerName("");
                } else {
                    Device de = deviceService.getCurrentDevice(device.getLivePeerId());
                    if (de != null) {
                        device.setLivePeerName(de.getName());
                    } else {
                        device.setLivePeerName(defaultLivePeerName);
                    }
                }
                UserDeviceOperation userDeviceOperation = new UserDeviceOperation();
                UserDeviceOperation udo = null;
                userDeviceOperation.setPeerId(device.getPeerId());
                userDeviceOperation.setUserId(pageParam.getUserId());
                List<UserDeviceOperation> list = userDeviceOperationMapper.select(userDeviceOperation);
                if (list != null && list.size() > 0) {
                    udo = list.get(0);
                }
                DeviceExtend deviceExtend = MyUtil.transfromDevice(device);
                if (udo == null) {
                    deviceExtend.setFavorite("0");
                    deviceExtend.setDescribes("");
                } else {
                    if (StringUtils.isBlank(udo.getDescribes())) {
                        deviceExtend.setDescribes("");
                    } else {
                        deviceExtend.setDescribes(udo.getDescribes());
                    }
                    if (udo.getFavorite() == null) {
                        deviceExtend.setFavorite("0");
                    } else {
                        deviceExtend.setFavorite(udo.getFavorite() + "");
                    }
                }

                if (StringUtils.isNotBlank(deviceExtend.getLivePeerId())) {
                    Device source = deviceService.getCurrentDevice(deviceExtend.getLivePeerId());
                    if (source != null) {
                        if (StringUtils.isNotBlank(source.getType())) {
                            deviceExtend.setLivePeerType(source.getType());
                        }
                        if (StringUtils.isNotBlank(source.getPlatform())) {
                            deviceExtend.setLiveDevicePlatform(source.getPlatform());
                        }
                    } else {
                        deviceExtend.setLivePeerType("null");
                        deviceExtend.setLiveDevicePlatform("null");
                    }
                } else {
                    deviceExtend.setLivePeerType("null");
                    deviceExtend.setLiveDevicePlatform("null");
                }
                result.add(deviceExtend);
            }
        }
//        logger.error("====getReceiverList ====3"+JSONObject.toJSONString(result));
        pb.setCurrentPageNum(pageParam.getPageNum());
        pb.setEveryPageNum(pageParam.getPageSize());

        if (result != null) {
            pb.setTotalNum(result.size());
        }
        if (pb.getTotalNum() == 0) {
            return pb;
        }
        long pageNumber = getPageNumber(result, pb);
        pb.setTotalPageNum(pageNumber);
        List<DeviceExtend> pageList = subPageList(result, pb);
        pb.setResultList(pageList);
//        logger.error("====getReceiverList ====4"+JSONObject.toJSONString(pageList));
        return pb;
    }

    /**
     *
     * @param peerId peerId
     * @return Device
     */
    public Device queryDeviceById(String peerId) {
        return deviceService.getCurrentDevice(peerId);
    }

    @Override
    public Result<Object> queryUserSourcelist(PageParam pageParam) throws Exception {
        log.info("===queryUserSourcelist=== begin pageParam:" + JSONObject.toJSONString(pageParam));
        String userId = pageParam.getUserId();
        String condition = pageParam.getCondition();
        List<Device> allSource = new ArrayList<Device>();
        // not exist ext
        Set<String> allSourcePeerId = null;

        log.info("===queryUserSourcelist==allSourcePeerId begin:" + System.currentTimeMillis());
        allSourcePeerId = queryAllUserSourcePeerId(userId, condition);
        List<String> tokenAnywhereIds = userFeignService.getTokenAnywhereIds(userId, null, false, condition);
        if (tokenAnywhereIds != null && tokenAnywhereIds.size() > 0) {
            allSourcePeerId.addAll(tokenAnywhereIds);
        }
        log.info("===queryUserSourcelist==queryAllSourcePeerId end:" + System.currentTimeMillis());
        if ( allSourcePeerId.size() > 0) {
            log.info("===queryUserSourcelist==allSource begin:" + System.currentTimeMillis());
            allSource = deviceService.listCurrentDevice(allSourcePeerId);
            log.info("===queryUserSourcelist==allSource end:" + JSONObject.toJSONString(allSource));
        }
        if (  allSourcePeerId.size() > 0) {
            Collections.sort(allSource, new ComparatorName());
        }

        if (allSource != null && allSource.size() > 0) {
            // 根据 peerId 字段去重
            allSource = allSource.stream()
                    .filter(MyUtil.distinctByKey(Device::getPeerId))
                    .collect(Collectors.toList());

//            allSource = listSort(allSource);
        }
        List result = new ArrayList();
        JSONObject anywhereResultMap = new JSONObject();
        JSONObject packResultMap = new JSONObject();
        //做分类
        List<Device> anywhereList ;
        List<Device> packList;
        log.info("All source in all type :" + JSONObject.toJSONString(allSource));
        if (!CollectionUtils.isEmpty(allSource)) {
            anywhereList = allSource.stream()
                    .parallel()
                    .filter(e -> e.getType().equals("T")
                            && StringUtils.isNotEmpty(e.getPlatform())
                            && Integer.parseInt(e.getPlatform()) > 9
                            && Integer.parseInt(e.getPlatform()) < 15)
                    .collect(Collectors.toList());
            log.info("All source in anywhereList :" + JSONObject.toJSONString(anywhereList));
            packList = allSource.stream().parallel()
                    .filter(e -> e.getType().equals("T")
                            && StringUtils.isNotEmpty(e.getPlatform())
                            && (Integer.parseInt(e.getPlatform()) > 14 || Integer.parseInt(e.getPlatform()) < 10))
                    .collect(Collectors.toList());
            log.error("All source in packList :" + JSONObject.toJSONString(packList));
            if (anywhereList.size() > 0) {
                anywhereList = listSortByPack(anywhereList);
                anywhereResultMap.put("TVU Anywhere", anywhereList);
                result.add(anywhereResultMap);
            }
            if (packList.size() > 0) {
                packList = listSortByPack(packList);
                packResultMap.put("TVU Pack", packList);
                result.add(packResultMap);
            }
        }
        log.info("===getAllDeviceSource=== END:" + System.currentTimeMillis());
        return ResultUtil.success(result);
    }

    @Override
    public Result<Object> queryGeoRecordSelection() throws Exception {
        Map map = new HashMap();
        map.put("selectionTime", selection);
        map.put("delayQueryTime", delayQueryTime);
        map.put("manualIncrementTime", manualIncrementTime);
        map.put("incrementalRangeTime", incrementalRangeTime);
        map.put("mapStep", mapStep);

        return ResultUtil.success(map);
    }

    /**
     *
     * @param vs vs
     * @param pb pb
     * @param <V> v
     * @param <T> t
     * @return int
     */
    public static <V, T> int getPageNumber(List<V> vs, PageBar<T> pb) {
        if (vs == null || vs.size() == 0) {
            return 0;
        }

        if (vs.size() % pb.getEveryPageNum() == 0) {
            return vs.size() / (int) pb.getEveryPageNum();
        } else {
            return vs.size() / (int) pb.getEveryPageNum() + 1;
        }
    }

    /**
     *
     * @param vs vs
     * @param pb pb
     * @param <T> t
     * @return List
     */
    public static <T> List<T> subPageList(List<T> vs, PageBar<T> pb) {
        int pageIndex = (int) pb.getCurrentPageNum();
        if (pageIndex < 1) {
            pageIndex = 1;
        } else {
            pageIndex = (int) Math.min(pageIndex, pb.getTotalPageNum());
        }
        pb.setCurrentPageNum(String.valueOf(pageIndex));
        if (vs.size() > 0) {
            return vs.subList((int) ((pageIndex - 1) * pb.getEveryPageNum()),
                    (int) Math.min(pageIndex * pb.getEveryPageNum(), vs.size()));
        } else {
            return null;
        }
    }

    /**
     * 非动态排序
     *
     * @param receiverList receiverList
     * @return List
     */
    public List<Device> listSort(List<Device> receiverList) {
        List<Device> cloudrList = new ArrayList<Device>();
        List<Device> onlineList = new ArrayList<Device>();
        List<Device> liveList = new ArrayList<Device>();
        List<Device> offlineList = new ArrayList<Device>();
        List<Device> resultList = new ArrayList<Device>();
        if (receiverList != null && receiverList.size() > 0) {
            for (Device device : receiverList) {
                if ("0".equals(device.getStatus()) && !"CloudR".equals(device.getName())) {
                    offlineList.add(device);
                } else if ("1".equals(device.getStatus()) && !"CloudR".equals(device.getName())) {
                    onlineList.add(device);
                } else if ("2".equals(device.getStatus()) && !"CloudR".equals(device.getName())) {
                    liveList.add(device);
                } else if ("CloudR".equals(device.getName())) {
                    cloudrList.add(device);
                } else if ("3".equals(device.getStatus())) {
                    onlineList.add(device);
                }
            }
        }
        // 离线按名称排序
        Collections.sort(offlineList, new Comparator<Device>() {
            @Override
            public int compare(Device device1, Device device2) {
                String nameOne = device1.getName().toUpperCase();
                String nameTwo = device2.getName().toUpperCase();
                return nameOne.compareTo(nameTwo);
            }
        });
        // 在线按名称排序
        Collections.sort(onlineList, new Comparator<Device>() {
            @Override
            public int compare(Device device1, Device device2) {
                String nameOne = device1.getName().toUpperCase();
                String nameTwo = device2.getName().toUpperCase();
                return nameOne.compareTo(nameTwo);
            }
        });
        // live按名称排序
        Collections.sort(liveList, new Comparator<Device>() {
            @Override
            public int compare(Device device1, Device device2) {
                String nameOne = device1.getName().toUpperCase();
                String nameTwo = device2.getName().toUpperCase();
                return nameOne.compareTo(nameTwo);
            }
        });

        resultList.addAll(cloudrList);// cloudr
        resultList.addAll(liveList);// live
        resultList.addAll(onlineList);// online
        resultList.addAll(offlineList);// offline
        return resultList;
    }

    /**
     * 非动态排序
     *
     * @param receiverList  receiverList
     * @return List
     */
    public List<Device> listSortByPack(List<Device> receiverList) {
        List<Device> cloudrList = new ArrayList<Device>();
        List<Device> onlineList = new ArrayList<Device>();
        List<Device> liveList = new ArrayList<Device>();
        List<Device> offlineList = new ArrayList<Device>();
        List<Device> resultList = new ArrayList<Device>();
        if (receiverList != null && receiverList.size() > 0) {
            for (Device device : receiverList) {
                if ("0".equals(device.getStatus()) && !"CloudR".equals(device.getName())) {
                    offlineList.add(device);
                } else if ("1".equals(device.getStatus()) && !"CloudR".equals(device.getName())) {
                    onlineList.add(device);
                } else if ("2".equals(device.getStatus()) && !"CloudR".equals(device.getName())) {
                    liveList.add(device);
                } else if ("CloudR".equals(device.getName())) {
                    cloudrList.add(device);
                } else if ("3".equals(device.getStatus())) {
                    onlineList.add(device);
                }
            }
        }
        // 离线按名称排序
        Collections.sort(offlineList, new Comparator<Device>() {
            @Override
            public int compare(Device device1, Device device2) {
                String nameOne = device1.getName().toUpperCase();
                String nameTwo = device2.getName().toUpperCase();
                return nameOne.compareTo(nameTwo);
            }
        });
        // 在线按名称排序
        Collections.sort(onlineList, new Comparator<Device>() {
            @Override
            public int compare(Device device1, Device device2) {
                String nameOne = device1.getName().toUpperCase();
                String nameTwo = device2.getName().toUpperCase();
                return nameOne.compareTo(nameTwo);
            }
        });
        // live按名称排序
        Collections.sort(liveList, new Comparator<Device>() {
            @Override
            public int compare(Device device1, Device device2) {
                String nameOne = device1.getName().toUpperCase();
                String nameTwo = device2.getName().toUpperCase();
                return nameOne.compareTo(nameTwo);
            }
        });

        resultList.addAll(cloudrList);// cloudr
        resultList.addAll(onlineList);// online
        resultList.addAll(liveList);// live
        resultList.addAll(offlineList);// offline
        return resultList;
    }

    /**
     * 动态排序
     *
     * @param receiverList
     * @return
     */
    private List<Device> listDynamicSort(List<Device> receiverList) {
        List<Device> dynamicSortlist = new ArrayList<Device>();
        List<Device> cloudrList = new ArrayList<Device>();
        List<Device> resultList = new ArrayList<Device>();
        if (receiverList != null && receiverList.size() > 0) {
            for (Device device : receiverList) {
                if ("CloudR".equals(device.getName())) {
                    cloudrList.add(device);
                } else {
                    dynamicSortlist.add(device);
                }
            }
        }
        Collections.sort(dynamicSortlist, new Comparator<Device>() {
            @Override
            public int compare(Device device1, Device device2) {
                String nameOne = device1.getName().toUpperCase();
                String nameTwo = device2.getName().toUpperCase();
                return nameOne.compareTo(nameTwo);
            }
        });
        resultList.addAll(cloudrList);
        resultList.addAll(dynamicSortlist);
        return resultList;
    }

    private Map<String, Device> getAvailalbeString(List<Device> list) {
        Map<String, Device> availalbeStr = new HashMap<String, Device>();
        if (list != null && list.size() > 0) {
            for (Device info : list) {
                availalbeStr.put(info.getPeerId(), info);
            }
        }
        return availalbeStr;
    }

    /**
     *
     * @param pageParam  pageParam
     * @return List
     * @throws Exception 编译异常
     */
    public List<String> listPeerIdsByUserId(PageParam pageParam) throws Exception {
        String userId = pageParam.getUserId();
        String condition = pageParam.getCondition();
        String favorite = pageParam.getFavorite();
/*        DeviceSearchStatus deviceSearchStatus =pageParam.getDeviceSearchStatus();
        List<String> stus = deviceSearchStatus.getStatusList();
        int pageNum = pageParam.getPageNum();
        int pageSiza = pageParam.getPageSize();
        PageHelper.startPage(pageNum, pageSiza);*/
        condition = MyUtil.formatCondition(condition);
        List<String> list = userDeviceMapper.listRIds(userId, condition, favorite);

        if (list == null) {
            list = new ArrayList<>();
        }

        return list;
    }

    @Override
    public PageBar<Device> getAllDeviceSource(PageParam pageParam, String role) throws Exception {
        log.info("===getAllDeviceSource=== begin:" + System.currentTimeMillis());
        String userId = pageParam.getUserId();
        String rid = pageParam.getPeerId();
        String condition = pageParam.getCondition();
        List<Device> allSource = new ArrayList<Device>();
        // not exist ext
        Set<String> allSourcePeerId ;

        log.info("===getAllDeviceSource==allSourcePeerId begin:" + System.currentTimeMillis());
        allSourcePeerId = queryAllSourcePeerId(rid, userId, condition);
        log.info("===getAllDeviceSource==queryAllSourcePeerId end:" + System.currentTimeMillis());
        if ( allSourcePeerId.size() > 0) {
            log.info("===getAllDeviceSource==allSource begin:" + System.currentTimeMillis());
            allSource = deviceService.listCurrentDevice(allSourcePeerId);
            log.info("===getAllDeviceSource==allSource end:" + System.currentTimeMillis());
        }
        if ( allSourcePeerId.size() > 0) {
            Collections.sort(allSource, new ComparatorName());
        }
        // ext sort next
        log.info("===getAllDeviceSource==queryAllUserExtPeerId begin:" + System.currentTimeMillis());
        List<String> extPeerIdList = queryAllUserExtPeerId(userId, condition);
        log.info("===getAllDeviceSource==queryAllUserExtPeerId end:" + System.currentTimeMillis());
        if (extPeerIdList != null && extPeerIdList.size() > 0) {
            log.info("===getAllDeviceSource==extSource start:" + System.currentTimeMillis());
            List<Device> extSource = deviceService.listCurrentDevice(extPeerIdList);
            log.info("===getAllDeviceSource==extSource end:" + System.currentTimeMillis());
            Collections.sort(extSource, new ComparatorName());
            allSource.addAll(extSource);
        }

        try {

            // 以下的逻辑就是查询出来的 Grid,要将 Grid 的 livePeerId 和当前用户下的R取交集
            List<AcceptedGrid> gridByUserId = gridFeignService.getGridByUserId(userId, condition);

            // 因为后面需要对 Peer Id 进行比较所以 Peer Id 全部转成小写
            gridByUserId.forEach(x ->  x.setPeerId(x.getPeerId().toLowerCase()));

            if (!CollectionUtils.isEmpty(gridByUserId) && !CollectionUtils.isEmpty(allSourcePeerId)) {
                // 从 Grid 请求过来的 list 中排除本来就是用户下的 source
                gridByUserId = gridByUserId
                        .stream()
                        .filter(x -> allSourcePeerId.contains(x.getPeerId().toLowerCase()) )
                        .collect(Collectors.toList());
            }


            if (!CollectionUtils.isEmpty(gridByUserId)) {
                // 提取查询出来的 Grid peerid
                List<String> gridIds = gridByUserId.stream().map(AcceptedGrid::getPeerId).collect(Collectors.toList());
                List<Device> gridDevices = deviceService.listCurrentDevice(gridIds);

                // 添加到最终的查询列表中
                allSource.addAll(gridDevices);

                if (!CollectionUtils.isEmpty(gridDevices)) {
                    // 查询用户下的所有可用的 R
                    PageParam rpageParam = new PageParam()
                            .setUserId(userId)
                            .setCondition(null)
                            .setFavorite("0");

                    // 查询用户下所有的R
                    List<String> rpids = listPeerIdsByUserId(rpageParam);

                    for (Device device : gridDevices) {

                        if (StringUtils.equals(LocalConstant.DeviceStatus.LIVING, device.getStatus())) {
                            String livePeerId = device.getLivePeerId();
                            String livePeerName = device.getLivePeerName();

                            if (StringUtils.isEmpty(livePeerId) || StringUtils.isEmpty(livePeerName)) {
                                continue;
                            }

                            List<String> livePeerIdList = Arrays.asList(livePeerId.split(";"));
                            List<String> livePeerNameList = Arrays.asList(livePeerName.split(";"));
                            List<Device> liveDevices = new ArrayList<>();

                            // 查出来 source 可用的 R 中包含 live peer id 才 add 到 liveDevices 中
                            // 目前情况从 Grid 请求过来的源只可能和这个用户下的一个 R live
                            for (int i = 0; i < livePeerIdList.size(); i++) {
                                if (rpids.contains(livePeerIdList.get(i))) {
                                    Device liveDevice = new Device();
                                    liveDevice.setLivePeerId(livePeerIdList.get(i));
                                    liveDevice.setLivePeerName(livePeerNameList.get(i));
                                    liveDevices.add(liveDevice);
                                }
                            }

                            // 如果 source 正在live的R中没有一个是当前用户下的则将状态改为 online
                            if (CollectionUtils.isEmpty(liveDevices)) {
                                device.setStatus(LocalConstant.DeviceStatus.ONLINE);
                                device.setLivePeerId("")
                                        .setLivePeerName("");
                            } else {

                                String allLivePeerId = liveDevices
                                        .stream()
                                        .map(Device::getLivePeerId)
                                        .collect(Collectors.joining(";"));
                                String allLivePeerName = liveDevices
                                        .stream()
                                        .map(Device::getLivePeerName)
                                        .collect(Collectors.joining(";"));

                                device.setLivePeerId(allLivePeerId);
                                device.setLivePeerName(allLivePeerName);
                            }

                        }

                    }
                }
            }
        } catch (Exception e) {
            log.error("getGridByUserId failed userId [{}] ", userId, e);
        }
        //添加rtil和glink
        SearchDeviceParam searchDeviceParam = new SearchDeviceParam();
        searchDeviceParam.setRid(pageParam.getPeerId());
        searchDeviceParam.setCondition(pageParam.getCondition());
        List<Device> deviceExtendList = getExtentExtenalSource(searchDeviceParam);
        if (deviceExtendList.size() > 0) {
            allSource.addAll(deviceExtendList);
        }
        if (allSource != null && allSource.size() > 0) {
            // 根据 peerId 字段去重
//            allSource = allSource.stream().filter(MyUtil.distinctByKey(Device::getPeerId)).collect(Collectors.toList());

            allSource = listSort(allSource);
        }

        PageBar<Device> pb = new PageBar<Device>();
        pb.setCurrentPageNum(pageParam.getPageNum());
        pb.setEveryPageNum(pageParam.getPageSize());
        if (!CollectionUtils.isEmpty(allSource)){
            pb.setTotalNum(allSource.size());
        }

        List<Device> results ;
        long pageNumber = 0;
        pageNumber = getPageNumber(allSource, pb);
        if (allSource != null) {
            results = subPageList(allSource, pb);

            pb.setTotalPageNum(pageNumber);
            if (results == null) {
                pb.setResultList(allSource);
            } else {
                pb.setResultList(results);
            }
        }
        log.info("===getAllDeviceSource=== END:" + System.currentTimeMillis());
        return pb;
    }

    /**
     *
     * @param searchDeviceParam searchDeviceParam
     * @return List
     */
    public List<Device> getExtentExtenalSource(SearchDeviceParam searchDeviceParam) {
        //查询R端的sourceTypeList
        List<Device> deviceList = new ArrayList<>();
        String sourceTypeList = this.getRSourceListToRedis(searchDeviceParam.getRid());
        if (StringUtils.isEmpty(sourceTypeList)) {

            Result<String> result = null;
            //根据Rid 查询R的sourceTypeList
            try {
                result = this.getRSourceTypeList(searchDeviceParam.getRid());
                if (result != null) {
                    this.setRSourceListToRedis(searchDeviceParam.getRid(), result.getResult());
                }
            } catch (Exception e) {
                log.error("getRSourceTypeList Exception:[{}]", e);
            }
        }
        if (!StringUtils.isEmpty(sourceTypeList)) {
            //根据sourceTypeList查询对应source
            if (sourceTypeList.contains("GLinkPeerManager")) {//包含glink

                PageInfo<ExtendExternal> gLinkList = deviceService.getGLinkList(searchDeviceParam);
                if (gLinkList.getList().size() > 0) {
//                    rPairGLinkInitVoGrid.setContent(gLinkList);
                    for (ExtendExternal extendExternal : gLinkList.getList()) {
                        Device device = new Device();
                        device.setId(extendExternal.getId());
                        device.setType(extendExternal.getType());
                        device.setPeerId(extendExternal.getPeerId());
                        device.setUrl(extendExternal.getUrl());
                        device.setName(extendExternal.getName());
                        device.setStatus("1");
                        deviceList.add(device);
                    }
                }
            }
            if (sourceTypeList.contains("AgoraPeerManager")) {//RTIL //需要从R端获取
                try {
                    Result<String> rTILkList = this.getRTILList(searchDeviceParam.getRid());
                    if ("0x0".equals(rTILkList.getErrorCode())) {
                        if (rTILkList.getResult().equals("[]")) {
//                            rPairRTILInitVoGrid.setContent(null);
                        } else {
//                            rPairRTILInitVoGrid.setContent(rTILkList.getResult());
                        }

                        if (!StringUtils.isEmpty(rTILkList.getResult())) {
                            JSONArray rTILkListArr = JSON.parseArray(rTILkList.getResult());
                            if (rTILkListArr.size() > 0) {
                                for (int i = 0; i < rTILkListArr.size(); i++) {
                                    JSONObject object = (JSONObject) rTILkListArr.get(i);
                                    Device device = new Device();
                                    device.setPeerId(object.get("IdHex").toString());
                                    device.setUrl(object.get("PlaybackUrl").toString());
                                    device.setName(object.get("Name").toString());
                                    device.setStatus("1");
                                    device.setType("RTIL");
                                    deviceList.add(device);
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error("get RTIL Exception", e);
                }

            }
        }
        return deviceList;
    }

    /**
     *
     * @param rid rid
     * @return Result
     */
    public Result<String> getRTILList(String rid) {
        Map modelMap = new HashMap();
        modelMap.put("Name", "AgoraPeerManager");
        try {
            String params = MyUtil.MAPPER.writeValueAsString(modelMap);
            Result<String> rTIL = receiverControlService.command(rid, CommandConstant.GET_SOURCE_TYPE, params);
            return rTIL;
        } catch (JsonProcessingException e) {
            log.error("msg:{},e:{}",e.getMessage(),e);
        }

        return ResultUtil.error("get AgoraPeerManager error");
    }

    /**
     *
     * @param rid rid
     * @return String
     */
    public String getRSourceListToRedis(String rid) {
        String key = "source_type_list_" + rid;
        return (String) redisUtil.get(key);
    }

    /**
     *
     * @param rid rid
     * @param sourceTypeList sourceTypeList
     */
    public void setRSourceListToRedis(String rid, String sourceTypeList) {
        String key = "source_type_list_" + rid;
        redisUtil.set(key, sourceTypeList, 60L);
    }

    /**
     *
     * @param rid rid
     * @return Result
     */
    public Result<String> getRSourceTypeList(String rid) {
        Map modelMap = new HashMap();
        modelMap.put("ClientRequestId", UUID.randomUUID());
        try {
            String params = MyUtil.MAPPER.writeValueAsString(modelMap);
            return receiverControlService.command(rid, CommandConstant.WEBR_SOURCE_TYPE, params);
        } catch (JsonProcessingException e) {
            log.error("msg:{},e:{}",e.getMessage(),e);
        }
        return ResultUtil.paramError();
    }

    @Override
    public Result<Object> getAllDeviceSourceByPack(PageParam pageParam) throws Exception {
        log.error("===getAllDeviceSource=== begin pageParam:" + JSONObject.toJSONString(pageParam));
        String userId = pageParam.getUserId();
        String rid = pageParam.getPeerId();
        String condition = pageParam.getCondition();
        List<Device> allSource = new ArrayList<Device>();

        // not exist ext
        Set<String> allSourcePeerId ;
        Long startTime = System.currentTimeMillis();
        log.error("===getAllDeviceSource==allSourcePeerId begin StartTime:" + System.currentTimeMillis());
        //获取了所有得T、X、Token
        allSourcePeerId = queryAllSourcePeerId(rid, userId, condition);
        log.error("===getAllDeviceSource==allSourcePeerId one" + System.currentTimeMillis());
        log.error("===getAllDeviceSource==allSourcePeerId begin endTime:" + System.currentTimeMillis());
        List<String> tokenAnywhereIds = userFeignService.getTokenAnywhereIds(userId, rid, Boolean.FALSE, condition);
        log.error("===getAllDeviceSource==toke  nAnywhereIds end:" + JSONObject.toJSONString(tokenAnywhereIds));
        if (tokenAnywhereIds != null && tokenAnywhereIds.size() > 0) {
            allSourcePeerId.addAll(tokenAnywhereIds);
        }
        //获取所有得GridViaToken
        List<String> gridViaToken = userDeviceMapper.listUserTokenGridIds(userId, condition);
        if (!CollectionUtils.isEmpty(gridViaToken)) {
            allSourcePeerId.addAll(gridViaToken);
        }


        log.error("===getAllDeviceSource==queryAllSourcePeerId end:" + System.currentTimeMillis());
        if ( allSourcePeerId.size() > 0) {
            log.error("===getAllDeviceSource==allSource begin:" + System.currentTimeMillis());
            allSource = deviceService.listCurrentDevice(allSourcePeerId);
            log.error("===getAllDeviceSource==allSource end:" + JSONObject.toJSONString(allSource));
        }
        if ( allSourcePeerId.size() > 0) {
            Collections.sort(allSource, new ComparatorName());
        }
            // ext sort next
            log.error("===getAllDeviceSource==queryAllUserExtPeerId begin:" + System.currentTimeMillis());
            List<String> extPeerIdList = queryAllUserExtPeerId(userId, condition);
            log.error("===getAllDeviceSource==queryAllUserExtPeerId end:" + JSONObject.toJSONString(extPeerIdList));
            if (extPeerIdList != null && extPeerIdList.size() > 0) {
                log.error("===getAllDeviceSource==extSource start:" + System.currentTimeMillis());
                List<Device> extSource = deviceService.listCurrentDevice(extPeerIdList);
                log.error("===getAllDeviceSource==extSource end:" + JSONObject.toJSONString(extSource));
                Collections.sort(extSource, new ComparatorName());
                allSource.addAll(extSource);
            }
        try {

            // 以下的逻辑就是查询出来的 Grid,要将 Grid 的 livePeerId 和当前用户下的R取交集
            List<AcceptedGrid> gridByUserId = gridFeignService.getGridByUserId(userId, condition);

            if (!CollectionUtils.isEmpty(gridByUserId) && !CollectionUtils.isEmpty(allSourcePeerId)) {
                // 从 Grid 请求过来的 list 中排除本来就是用户下的 source
                // 因为后面需要对 Peer Id 进行比较所以 Peer Id 全部转成小写
                gridByUserId.forEach(x ->  x.setPeerId(x.getPeerId().toLowerCase()));

                if (!CollectionUtils.isEmpty(gridByUserId) && !CollectionUtils.isEmpty(allSourcePeerId)) {
                    // 从 Grid 请求过来的 list 中排除本来就是用户下的 source
                    gridByUserId = gridByUserId
                            .stream()
                            .filter(x -> allSourcePeerId.contains(x.getPeerId().toLowerCase()) )
                            .collect(Collectors.toList());
                }

            }

            if (!CollectionUtils.isEmpty(gridByUserId)) {
                // 提取查询出来的 Grid peerid
                List<String> gridIds = gridByUserId.stream().map(AcceptedGrid::getPeerId).collect(Collectors.toList());
                List<Device> gridDevices = deviceService.listCurrentDevice(gridIds);

                // 添加到最终的查询列表中
                allSource.addAll(gridDevices);

                if (!CollectionUtils.isEmpty(gridDevices)) {
                    // 查询用户下的所有可用的 R
                    PageParam rpageParam = new PageParam()
                            .setUserId(userId)
                            .setCondition(null)
                            .setFavorite("0");

                    // 查询用户下所有的R
                    List<String> rPids = listPeerIdsByUserId(rpageParam);

                    for (Device device : gridDevices) {

                        if (StringUtils.equals(LocalConstant.DeviceStatus.LIVING, device.getStatus())) {
                            String livePeerId = device.getLivePeerId();
                            String livePeerName = device.getLivePeerName();

                            if (StringUtils.isEmpty(livePeerId) || StringUtils.isEmpty(livePeerName)) {
                                continue;
                            }

                            List<String> livePeerIdList = Arrays.asList(livePeerId.split(";"));
                            List<String> livePeerNameList = Arrays.asList(livePeerName.split(";"));
                            List<Device> liveDevices = new ArrayList<>();

                            // 查出来 source 可用的 R 中包含 live peer id 才 add 到 liveDevices 中
                            // 目前情况从 Grid 请求过来的源只可能和这个用户下的一个 R live
                            for (int i = 0; i < livePeerIdList.size(); i++) {
                                if (rPids.contains(livePeerIdList.get(i))) {
                                    Device liveDevice = new Device();
                                    liveDevice.setLivePeerId(livePeerIdList.get(i));
                                    liveDevice.setLivePeerName(livePeerNameList.get(i));
                                    liveDevices.add(liveDevice);
                                }
                            }

                            // 如果 source 正在live的R中没有一个是当前用户下的则将状态改为 online
                            if (CollectionUtils.isEmpty(liveDevices)) {
                                device.setStatus(LocalConstant.DeviceStatus.ONLINE);
                                device.setLivePeerId("")
                                        .setLivePeerName("");
                            } else {

                                String allLivePeerId = liveDevices
                                        .stream()
                                        .map(Device::getLivePeerId)
                                        .collect(Collectors.joining(";"));
                                String allLivePeerName = liveDevices
                                        .stream()
                                        .map(Device::getLivePeerName)
                                        .collect(Collectors.joining(";"));

                                device.setLivePeerId(allLivePeerId);
                                device.setLivePeerName(allLivePeerName);
                            }

                        }

                    }
                }
            }
        } catch (Exception e) {
            log.error("getGridByUserId failed userId [{}] ", userId, e);
        }

        if (allSource != null && allSource.size() > 0) {
            // 根据 peerId 字段去重
            allSource = allSource.stream()
                    .filter(MyUtil.distinctByKey(Device::getPeerId))
                    .collect(Collectors.toList());

//            allSource = listSort(allSource);
        }
        List result = new ArrayList();
        JSONObject anywhereResultMap = new JSONObject();
        JSONObject packResultMap = new JSONObject();
        JSONObject gridResultMap = new JSONObject();
        JSONObject externalResultMap = new JSONObject();
        JSONObject localSdiResultMap = new JSONObject();
        //做分类
        List<Device> anywhereList = new ArrayList<>();
        List<Device> packList = new ArrayList<>();
        List<Device> gridList = new ArrayList<>();
        List<Device> extList = new ArrayList<>();
        //localSdi
        List<Device> localSdiList = this.getLocalSdi(rid, condition);
        log.error("All source in all type :" + JSONObject.toJSONString(allSource));
        if(!CollectionUtils.isEmpty(allSource) ) {
            anywhereList = allSource.stream()
                    .parallel()
                    .filter(e -> e.getType().equals("T")
                            && StringUtils.isNotEmpty(e.getPlatform())
                            && Integer.parseInt(e.getPlatform()) > 9
                            && Integer.parseInt(e.getPlatform()) < 15)
                    .collect(Collectors.toList());
            log.error("All source in anywhereList :" + JSONObject.toJSONString(anywhereList));
            packList = allSource.stream().parallel()
                    .filter(e -> e.getType().equals("T")
                            && (StringUtils.isEmpty(e.getPlatform()) || (StringUtils.isNotEmpty(e.getPlatform())
                            && (Integer.parseInt(e.getPlatform()) > 14 || Integer.parseInt(e.getPlatform()) < 10))))
                    .collect(Collectors.toList());
            log.error("All source in packList :" + JSONObject.toJSONString(packList));
            gridList = allSource.stream()
                    .parallel()
                    .filter(e -> e.getType().equals("X"))
                    .collect(Collectors.toList());
            log.error("All source in gridList :" + JSONObject.toJSONString(gridList));
            extList = allSource.stream()
                    .parallel()
                    .filter(e -> e.getType().equals("Ext")
                            || e.getType().equals("YouTube")
                            || e.getType().equals("ext")
                            || e.getType().equals("SMPTE2022"))
                    .collect(Collectors.toList());
            log.error("All source in extList :" + JSONObject.toJSONString(extList));
            if (anywhereList.size() > 0) {
                anywhereList = listSortByPack(anywhereList);
                anywhereResultMap.put("TVU Anywhere", anywhereList);
                result.add(anywhereResultMap);
            } else {
                if (pageParam.isExport()) {
                    anywhereResultMap.put("TVU Anywhere", anywhereList);
                    result.add(anywhereResultMap);
                }
            }
            if (packList.size() > 0) {
                packList = listSortByPack(packList);
                packResultMap.put("TVU Pack", packList);
                result.add(packResultMap);
            } else {
                if (pageParam.isExport()) {
                    packResultMap.put("TVU Pack", packList);
                    result.add(packResultMap);
                }
            }
            if (gridList.size() > 0) {
                gridList = listSortByPack(gridList);
                gridResultMap.put("Grid", gridList);
                result.add(gridResultMap);
            } else {
                if (pageParam.isExport()) {
                    gridResultMap.put("Grid", gridList);
                    result.add(gridResultMap);
                }
            }
            //MyReceiver界面默认此参数是false,走以下逻辑,取extSource,Device界面export参数为true,排除此逻辑,不再显示ext
            if (!pageParam.isExport()) {
                if (extList.size() > 0) {
                    extList = listSortByPack(extList);
                    externalResultMap.put("External", extList);
                    result.add(externalResultMap);
                }
            }
            if (CollectionUtils.isEmpty(localSdiList)) {
                if (pageParam.isExport()) {
                    localSdiResultMap.put("Local SDI", new ArrayList<>());
                    result.add(localSdiResultMap);
                }
            } else {
                localSdiResultMap.put("Local SDI", localSdiList);
                result.add(localSdiResultMap);
            }
            log.error("===getAllDeviceSource=== END:" + System.currentTimeMillis());
            try {
                log.error("getAllDeviceSource Excute Time==" + (System.currentTimeMillis() - startTime));
            } catch (Exception e) {
                log.error("===================getAllDeviceSource==========:", System.currentTimeMillis(), e);
            }
            return ResultUtil.success(result);
        }
        return  ResultUtil.success(result);

    }

    private List<Device> getLocalSdi(String rid, String condition) {
        try {
            //LocalSdi
            log.error("===getAllDeviceSource==queryLocalSdiPeerId begin:[{}],rid:[{}]", System.currentTimeMillis(), rid);
            List<Device> localSdiDevices = deviceService.getLocalSDIFromWebR(rid);
            log.error("===getAllDeviceSource==queryLocalSdiPeerId end:[{}]", localSdiDevices);
            if (!CollectionUtils.isEmpty(localSdiDevices)) {
                if (StringUtils.isNotEmpty(condition)) {
                    localSdiDevices = localSdiDevices.stream().filter(s -> StringUtils.containsIgnoreCase(s.getName(), condition)
                            || StringUtils.containsIgnoreCase(s.getPeerId(), condition)).collect(Collectors.toList());
                }
                return localSdiDevices;
            }
        } catch (Exception e) {
            log.error("===getAllDeviceSource==queryLocalSdiPeerId,rid:[{}], exception:[{}]", rid, e);
        }
        return null;
    }

    // not exist ext
    private Set<String> queryAllSourcePeerId(String rid, String userId, String condition) throws Exception {

            List<String> sourceType = new ArrayList<String>();
            sourceType.add("T");
            sourceType.add("X");
            sourceType.add("Sdiin");
            sourceType.addAll(listExtType());
            List<String> userPeerIds = userDeviceMapper.listPeerIds(userId, sourceType, condition);
            // query source list
            List<String> packIdList = devicePairService.listRPairT(rid);
            log.error("get packIdList for pair R StartTime" + System.currentTimeMillis());
            List<String> gridIdList = devicePairService.listCacheRPairX(rid);
            log.error("get gridIdList for pair R EndTime:" + System.currentTimeMillis());
            List<String> allPeerIdList = new ArrayList<String>();
            if (packIdList != null && packIdList.size() > 0) {
                allPeerIdList.addAll(packIdList);
            }
            if (gridIdList != null && gridIdList.size() > 0) {
                allPeerIdList.addAll(gridIdList);
            }
            // filter peerId not bind with user
            allPeerIdList = allPeerIdList.stream().map(String::toLowerCase).collect(Collectors.toList());
            userPeerIds = userPeerIds.stream().map(String::toLowerCase).collect(Collectors.toList());
            allPeerIdList.retainAll(userPeerIds);

            // token pair anywhere

//        // 使用 tvucc-token 接口
//        List<String> tokenPeerIds = tokenFeignService.getRPairTbyRidAndUserId(userId, rid);
//        if (!CollectionUtils.isEmpty(tokenPeerIds)) {
//            List<String> tokenPairAnyWhereIdList = myDeviceMapper.filterByCondition(tokenPeerIds, condition);
////        List<String> tokenPairAnyWhereIdList = userDeviceMapper.listPairedTByR(rid, condition);
//            if (tokenPairAnyWhereIdList != null && tokenPairAnyWhereIdList.size() > 0) {
//                allPeerIdList.addAll(tokenPairAnyWhereIdList);
//            }
//        }

            Set<String> rids = new HashSet<>();
            rids.add(rid);
            Set<String> tokenPeerIds = tokenFeignService.listRsPairedTids(rids);
            if (!CollectionUtils.isEmpty(tokenPeerIds)) {
                List<String> tokenPairAnyWhereIdList = myDeviceMapper.filterByCondition(new ArrayList<>(tokenPeerIds), condition);
                if (tokenPairAnyWhereIdList != null && tokenPairAnyWhereIdList.size() > 0) {
                    allPeerIdList.addAll(tokenPairAnyWhereIdList);
                }
            }
            return new HashSet<>(allPeerIdList);

    }


    private Set<String> queryAllUserSourcePeerId(String userId, String condition) throws Exception {
        List<String> sourceType = new ArrayList<String>();
        sourceType.add("T");
        sourceType.addAll(listExtType());
        List<String> userPeerIds = userDeviceMapper.listPeerIds(userId, sourceType, condition);
        return new HashSet<>(userPeerIds);
    }

    /**
     *
     * @param userId userId
     * @param condition conditi on
     * @return List
     * @throws Exception 编译异常
     */
    public List<String> queryAllUserExtPeerId(String userId, String condition) throws Exception {
        List<String> typeList = listExtType();
        List<String> peerIdList = userDeviceMapper.listPeerIds(userId, typeList, condition);
        return peerIdList;
    }

    /**
     *
     * @return List
     */
    public List<String> listExtType() {
        String types = sourceType;
        String[] typeArr = types.split(",");
        return Arrays.asList(typeArr);
    }

    /**
     *
     * @param userDeviceOperation userDeviceOperation
     * @throws Exception 编译异常
     */
    public void updataUserDeviceOperation(UserDeviceOperation userDeviceOperation) throws Exception {
        UserDeviceOperation udo = new UserDeviceOperation();
        String peerId = userDeviceOperation.getPeerId();
        String userId = userDeviceOperation.getUserId();
        if (StringUtils.isNotBlank(peerId)) {
            udo.setPeerId(peerId);
        }
        if (StringUtils.isNotBlank(userId)) {
            udo.setUserId(userId);
        }

        List<UserDeviceOperation> list = userDeviceOperationMapper.select(udo);
        if (list != null && list.size() > 0) {
            udo = list.get(0);
            userDeviceOperation.setId(udo.getId());
            userDeviceOperationMapper.updateByPrimaryKeySelective(userDeviceOperation);
        } else {
            addUserDeviceOperation(userDeviceOperation);
        }

    }

    /**
     *
     * @param userDeviceOperation userDeviceOperation
     * @throws Exception 编译异常
     */
    public void addUserDeviceOperation(UserDeviceOperation userDeviceOperation) throws Exception {
        userDeviceOperation.setId(UUID.randomUUID().toString().replace("-", ""));
        userDeviceOperationMapper.insertSelective(userDeviceOperation);
    }

    /**
     *
     * @param userBehavior userBehavior
     * @param userId userId
     * @return PageBar
     */
    public PageBar<DeviceExtend> queryReceiver(UserBehavior userBehavior, String userId) {
//        logger.error("====queryRlist  UserBehavior1==" + JSONObject.toJSONString(userBehavior));
//        PageParam pageParam = new PageParam();
        PageParam pageParam = null;
        String rList = null;
        UserBehavior ubr = null;
        UserCondition uc = null;
        PageBar<DeviceExtend> pageBar = null;
        try {
            if (userBehavior == null) {
                userBehavior = new UserBehavior();
                userBehavior.setContent("");
            }
            pageParam = JsonUtil.toObject(userBehavior.getContent(), PageParam.class);
//            logger.error("====queryRlist  UserBehavior2==" + JSONObject.toJSONString(pageParam));
//            rList = "";
            ubr = new UserBehavior();
            uc = new UserCondition();

            if (pageParam == null) {
                pageParam = new PageParam();
                pageParam.setCondition("");
                DeviceSearchStatus searchStatus = new DeviceSearchStatus();
                searchStatus.setLive(true);
                searchStatus.setOffline(true);
                searchStatus.setOnline(true);
                searchStatus.setSort(true);
                pageParam.setDeviceSearchStatus(searchStatus);
                pageParam.setFavorite("0");
                pageParam.setType("dn");
                pageParam.setLanguage("en-US");
            }
            pageParam.setUserId(userId);
            ubr.setUserId(userId);
            uc.setUserId(userId);
        } catch (Exception e) {
           log.error("====queryRlist UserBehavior33 exception====" + e);
        }
        try {
            if (ubr != null) {
                ubr.setRemark("queryRlist");
                ubr.setContent(JsonUtil.toJsonStr(pageParam));
                ubr.setUpdateTime(System.currentTimeMillis() + "");
            }

            if (pageParam!=null) {
                ubr.setPn(pageParam.getType());

                if (StringUtils.isNotBlank(pageParam.getCondition())) {
                    uc.setCondition(pageParam.getCondition());
                    updataUserCondition(uc);
                }

            userFeignService.updataUserBehavior(ubr);
            pageBar = getReceiverList(pageParam);
            }


        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return pageBar;

    }

    @Override
    public List<String> getBindTRPeerIdList(String userId) {
        return userDeviceMapper.getBindTRPeerIdList(userId);
    }

    /**
     *
     * @param userCondition userCondition
     * @throws Exception 编译异常
     */
    public void updataUserCondition(UserCondition userCondition) throws Exception {
        UserCondition uc = this.selectUserConditionByCondition(userCondition.getCondition());
        if (uc == null) {
            userCondition.setId(MyUtil.getUUID());
            userCondition.setCreatTime(System.currentTimeMillis());
            userCondition.setUpdateTime(System.currentTimeMillis());
            userCondition.setDeleteFlag(0);
            userConditionMapper.insert(userCondition);
        } else {
            userCondition.setId(uc.getId());
            userCondition.setUpdateTime(System.currentTimeMillis());
            userConditionMapper.updateByPrimaryKeySelective(userCondition);
        }
    }

    /**
     *
     * @param condition condition
     * @return UserCondition
     * @throws Exception 编译异常
     */
    public UserCondition selectUserConditionByCondition(String condition) throws Exception {
        UserCondition userCondition = new UserCondition();
        userCondition.setCondition(condition);
        return userConditionMapper.selectOne(userCondition);
    }

    @Override
    public void extracted(PageParam pageParam, HttpServletResponse response,String role) throws Exception {
        Result<Object> allSource ;

        allSource = this.getAllDeviceSourceByUserOrRid(pageParam,role);

        List<JSONObject> str = (List<JSONObject>) allSource.getResult();
        List<List<DeviceVo>> listAll = new ArrayList<>();
        List<DeviceVo> anywhereList = new ArrayList<>();
        List<DeviceVo> packList = new ArrayList<>();
        List<DeviceVo> gridList = new ArrayList<>();
        List<DeviceVo> localSDIList = new ArrayList<>();

        JSONObject anywhereResultMap = str.get(0);
        if (anywhereResultMap.get("TVU Anywhere") != null) {
            List<Device> anywhere = (List<Device>) anywhereResultMap.get("TVU Anywhere");
            for (Device device : anywhere) {
                DeviceVo deviceVo = new DeviceVo();
                deviceVo.setCount(i++)
                        .setName(device.getName())
                        .setPeerId(device.getPeerId())
                        .setType("TVU Anywhere");
                anywhereList.add(deviceVo);
            }
        }
        listAll.add(anywhereList);
        JSONObject packResultMap = str.get(1);
        if (packResultMap.get("TVU Pack") != null) {
            List<Device> pack = (List<Device>) packResultMap.get("TVU Pack");
            for (Device device : pack) {
                DeviceVo deviceVo = new DeviceVo();
                deviceVo.setCount(i++)
                        .setName(device.getName())
                        .setPeerId(device.getPeerId())
                        .setType("TVU Pack");
                packList.add(deviceVo);
            }
        }
        listAll.add(packList);
        JSONObject gridResultMap = str.get(2);
        if (gridResultMap.get("Grid") != null) {
            List<Device> grid = (List<Device>) gridResultMap.get("Grid");
            for (Device device : grid) {
                DeviceVo deviceVo = new DeviceVo();
                deviceVo.setCount(i++)
                        .setName(device.getName())
                        .setPeerId(device.getPeerId())
                        .setType("Grid");
                gridList.add(deviceVo);
            }
        }
        listAll.add(gridList);
        JSONObject localSDIResultMap = str.get(3);
        if (localSDIResultMap.get("Local SDI") != null) {
            List<Device> localSDI = (List<Device>) localSDIResultMap.get("Local SDI");
            for (Device device : localSDI) {
                DeviceVo deviceVo = new DeviceVo();
                deviceVo.setCount(i++)
                        .setName(device.getName())
                        .setPeerId(device.getPeerId())
                        .setType("Local SDI");
                localSDIList.add(deviceVo);
            }
            i = 1;
        }
        listAll.add(localSDIList);

        String[] heads = {"#", "Device Name", "PeerId", "Type"};

        OutputStream out = response.getOutputStream();
        XSSFWorkbook workbook = new XSSFWorkbook();
        ExcelUtil.exportExcel(workbook, 0, "BindDevice List", heads, listAll, pageParam);
        response.setContentType("application/x-msdownload");
        response.setHeader("Content-Disposition", "attachment; filename= BindDevice.xlsx");
        workbook.write(out);
        if (out != null) {
            out.close();
        }
    }


    @Override
    public Result<Object> getAllDeviceSourceByUserOrRid(PageParam pageParam,String role) throws Exception {
        String rid = pageParam.getPeerId();

        String userId = pageParam.getUserId();
        String condition = pageParam.getCondition();
        List<Device> allSource = new ArrayList<>();
        List<Device> collect ;
        Set<String> allSourcePeerId = new HashSet<>();
        //根据Rid,获取所有通过Token配对的Device设备信息
        List<String> tokenPairDeviceByRid = tokenFeignService.getPairTByRid(rid);
        if (!CollectionUtils.isEmpty(tokenPairDeviceByRid)) {
            allSourcePeerId.addAll(tokenPairDeviceByRid);
        }

        //根据Rid,获取所有通过gcs配对的Device设备信息
        List<String> gcsPairDeviceByRid = gcsManageFeignService.listRPairedX(rid);
        if (!CollectionUtils.isEmpty(gcsPairDeviceByRid)) {
            allSourcePeerId.addAll(gcsPairDeviceByRid);
        }

        //根据Rid,获取所有通过Tpc配对的Device设备信息
        Set<String> tpcRid = new HashSet<>();
        tpcRid.add(rid);
        Result<Set<String>> results = tpcFeignService.getTListPairedByRIds(tpcRid);
        if (results != null && results.assertSuccess()) {
            Set<String> tListPairedByRIds = results.getResult();
            if (!CollectionUtils.isEmpty(tListPairedByRIds)) {
                allSourcePeerId.addAll(tListPairedByRIds);
            }
        }
        //如果账号是普通用户,则查询出用户下的全部device, 考虑到一部分anywhere信息存储数据库的问题,需要去去token服务,查出通过userId,和Rid配对的anywhere,和之前的查询出全部的取交集
        if (StringUtils.equals(LocalConstant.UserRole.ADMIN, role) || StringUtils.equals(LocalConstant.UserRole.USER, role)) {
            Set<String> userDevice = userDeviceMapper.getDeviceIdByUser(userId);
            List<String> tokenPairDeviceByRidAndUserId = tokenFeignService.getPairTByUserIdAndRid(rid,userId);
            userDevice.addAll(tokenPairDeviceByRidAndUserId);
            userDevice.retainAll(allSourcePeerId);
        }
        if ( allSourcePeerId.size() > 0) {
            allSource = deviceService.listCurrentDevice(allSourcePeerId);
        }
        // ext sort next
        List<String> extPeerIdList = queryAllUserExtPeerId(userId, condition);
        if (extPeerIdList != null && extPeerIdList.size() > 0) {
            List<Device> extSource = deviceService.listCurrentDevice(extPeerIdList);
            Collections.sort(extSource, new ComparatorName());
            allSource.addAll(extSource);
        }

            if (allSource != null && allSource.size() > 0) {
                // 根据 peerId 字段去重
                allSource = allSource.stream()
                        .filter(MyUtil.distinctByKey(Device::getPeerId))
                        .collect(Collectors.toList());

            }
            //前端传递搜索条件condition,后端使用filter过滤,做出类似模糊查询的功能
        if (StringUtils.isNotEmpty(pageParam.getCondition())){
             collect = allSource.stream().filter(Device ->
                    StringUtils.containsIgnoreCase(Device.getPeerId(),pageParam.getCondition()) ||
                            StringUtils.containsIgnoreCase(Device.getName(),pageParam.getCondition())).collect(Collectors.toList());
        }else {
            collect=allSource;
        }


            List result = new ArrayList();
            JSONObject anywhereResultMap = new JSONObject();
            JSONObject packResultMap = new JSONObject();
            JSONObject gridResultMap = new JSONObject();
            JSONObject localSdiResultMap = new JSONObject();
            JSONObject externalResultMap = new JSONObject();
            //做分类
            List<Device> extList ;
            List<Device> anywhereList = new ArrayList<>();
            List<Device> packList = new ArrayList<>();
            List<Device> gridList = new ArrayList<>();
            //localSdi
            List<Device> localSdiList = this.getLocalSdi(rid, condition);
            log.error("All source in all type :" + JSONObject.toJSONString(collect));
            if(!CollectionUtils.isEmpty(collect)){
            anywhereList = collect.stream()
                    .parallel()
                    .filter(e -> e.getType().equals("T")
                            && StringUtils.isNotEmpty(e.getPlatform())
                            && Integer.parseInt(e.getPlatform()) > 9
                            && Integer.parseInt(e.getPlatform()) < 15)
                    .collect(Collectors.toList());
            log.error("All source in anywhereList :" + JSONObject.toJSONString(anywhereList));
            packList = collect.stream().parallel()
                    .filter(e -> e.getType().equals("T")
                            && (StringUtils.isEmpty(e.getPlatform()) || (StringUtils.isNotEmpty(e.getPlatform())
                            && (Integer.parseInt(e.getPlatform()) > 14 || Integer.parseInt(e.getPlatform()) < 10))))
                    .collect(Collectors.toList());
            log.error("All source in packList :" + JSONObject.toJSONString(packList));
            gridList = collect.stream()
                    .parallel()
                    .filter(e -> e.getType().equals("X"))
                    .collect(Collectors.toList());
            log.error("All source in gridList :" + JSONObject.toJSONString(gridList));
            extList = collect.stream()
                        .parallel()
                        .filter(e -> e.getType().equals("Ext")
                                || e.getType().equals("YouTube")
                                || e.getType().equals("SMPTE2022"))
                        .collect(Collectors.toList());
            log.error("All source in extList :" + JSONObject.toJSONString(extList));


                if (anywhereList.size() > 0) {
                anywhereList = listSortByPack(anywhereList);
                anywhereResultMap.put("TVU Anywhere", anywhereList);
                result.add(anywhereResultMap);
            } else {
                if (pageParam.isExport()) {
                    anywhereResultMap.put("TVU Anywhere", anywhereList);
                    result.add(anywhereResultMap);
                }
            }
            if (packList.size() > 0) {
                packList = listSortByPack(packList);
                packResultMap.put("TVU Pack", packList);
                result.add(packResultMap);
            } else {
                if (pageParam.isExport()) {
                    packResultMap.put("TVU Pack", packList);
                    result.add(packResultMap);
                }
            }
            if (gridList.size() > 0) {
                gridList = listSortByPack(gridList);
                gridResultMap.put("Grid", gridList);
                result.add(gridResultMap);
            } else {
                if (pageParam.isExport()) {
                    gridResultMap.put("Grid", gridList);
                    result.add(gridResultMap);
                }
            }
                //MyReceiver界面默认此参数是false,走以下逻辑,取extSource,Device界面export参数为true,排除此逻辑,不再显示ext
            if (!pageParam.isExport()) {
                    if (extList.size() > 0) {
                        extList = listSortByPack(extList);
                        externalResultMap.put("External", extList);
                        result.add(externalResultMap);
                    }
            }

                if (CollectionUtils.isEmpty(localSdiList)) {
                if (pageParam.isExport()) {
                    localSdiResultMap.put("Local SDI", new ArrayList<>());
                    result.add(localSdiResultMap);
                }
            } else {
                localSdiResultMap.put("Local SDI", localSdiList);
                result.add(localSdiResultMap);
            }
            return ResultUtil.success(result);
        }
            //如果没有任何数据,也要返回空集合.否则导出到excel表格时会报错.
        anywhereResultMap.put("TVU Anywhere", anywhereList);
        packResultMap.put("TVU Pack", packList);
        gridResultMap.put("Grid", gridList);
        localSdiResultMap.put("Local SDI", localSdiList);
        result.add(anywhereResultMap);
        result.add(packResultMap);
        result.add(gridResultMap);
        result.add(localSdiResultMap);

        return ResultUtil.success(result);
    }

    @Override
    public void deviceStatusChanged(String message) throws IOException {
        //1.获取接送Node
        JsonNode jsonNode = MyUtil.MAPPER.readTree(message);
        //2.解析jsonNode
        //2.1.查看是否包括peerId
        if (!jsonNode.has("peerId")) {
            log.error("parseMessageAndGetPeerId failed message not contain peerId message:{}", message);
            return;
        }
        String peerId = jsonNode.get("peerId").asText();
        //2.2.查看是否包括data
        if (!jsonNode.has("data")) {
            log.error("parseMessageAndGetPeerId failed message not contain data message:{}", message);
            return;
        }
        //3.解析data
        JsonNode data = jsonNode.get("data");
        if (data.has("status")) {
            JsonNode statusChange = data.get("status");
            if (statusChange.has("old") && statusChange.has("new")) {
                String oldStatus = statusChange.get("old").asText();
                String newStatus = statusChange.get("new").asText();
                DeviceReport deviceReport = new DeviceReport();
                DeviceReport.Date deviceData = new DeviceReport.Date();

                //当设备由不在线变成在线时,封装消息体,目前是partyline消费
                if (LocalConstant.DeviceStatus.OFFLINE.equals(oldStatus) && LocalConstant.DeviceStatus.ONLINE.equals(newStatus)) {
                    Device device = deviceService.getCurrentDevice(peerId);
                    String name = device.getName();
                    deviceReport.setOrigin("CC");
                    if (StringUtils.contains("fffffffbb", name.toLowerCase())) {
                        deviceReport.setOrigin("PP");
                    }
                    deviceData.setStatus(newStatus);
                    deviceData.setStatusMsg("online");
                    deviceReport.setCommand("online.report");
                    deviceReport.setDate(deviceData);
                    deviceReport.setTime(System.currentTimeMillis());
                    deviceReport.setMessageId(RandomUtil.generateString(12));
                    String messages = JSON.toJSONString(deviceReport);
                    log.error("Producer .send .message  offline->online: {}", message );
                    deviceExtraFeign.toRabbitMQByDeviceOnline(messages);
                }

                //当设备由在线变成live,封装消息体,
                if (LocalConstant.DeviceStatus.ONLINE.equals(oldStatus) && LocalConstant.DeviceStatus.LIVING.equals(newStatus)) {
                    deviceData.setStatus(newStatus);
                    deviceData.setStatusMsg("living");

                    Device device = deviceService.getCurrentDevice(peerId);
                    Device liveDevice = deviceService.getCurrentDevice(device.getLivePeerId());
                    String sourceName = liveDevice.getName();
                    String type = liveDevice.getType();
                    if (type.equals("R")) {
                        deviceData.setSourceType("Receiver");
                    }else if (type.equals("T")
                            && StringUtils.isNotEmpty(liveDevice.getPlatform())
                            && Integer.parseInt(liveDevice.getPlatform()) > 9
                            && Integer.parseInt(liveDevice.getPlatform()) < 15) {
                        deviceData.setSourceType("Tvu AnyWhere");
                    }else if (type.equals("T")
                            && (StringUtils.isEmpty(liveDevice.getPlatform()) || (StringUtils.isNotEmpty(liveDevice.getPlatform())
                            && (Integer.parseInt(liveDevice.getPlatform()) > 14 || Integer.parseInt(liveDevice.getPlatform()) < 10)))) {
                        deviceData.setSourceType("Pack");
                    }else if (type.equals("X")) {
                        deviceData.setSourceType("Grid");
                    }else if (type.equals("Ext")
                            || type.equals("YouTube")
                            || type.equals("ext")
                            || type.equals("SMPTE2022")){
                        deviceData.setSourceType("EXT");
                    }
                    deviceData.setSourceName(sourceName);
                    deviceData.setSourceId(device.getPeerId());
                    deviceReport.setOrigin("CC");
                    if (StringUtils.contains("fffffffbb", device.getName().toLowerCase())) {
                        deviceReport.setOrigin("PP");
                    }
                    deviceReport.setTime(System.currentTimeMillis());
                    deviceReport.setCommand("live.report");
                    deviceReport.setPeerId(peerId);
                    deviceReport.setDate(deviceData);
                    deviceReport.setMessageId(RandomUtil.generateString(12));
                    String messages = JSON.toJSONString(deviceReport);
                    log.error("Producer .send .message  online->live: {}", message );
                    deviceExtraFeign.toRabbitMQByDeviceLive(messages);
                }
                //如果以后还有服务需要消费,再加if判断扩展.
            }
        }
    }
}
